<?php

namespace app\api\controller;

use app\common\controller\Api;
use think\Db;
use Carbon\Carbon;

/**
 * 打卡统计控制器
 * @package app\index\controller
 */
class WorkStatistics extends Home
{
    public $noNeedLogin = [];


    /**
     * 打卡统计个人周统计
     */
    public function user_week()
    {
        if ($this->request->isGet()) {
            //打卡时间
            $getData = $this->request->get();
            if(empty($getData['type']) || empty($getData['start_time'])){
                $this->result('缺少参数','',204);
            }
            //月统计
            if($getData['type'] == '1'){
                $startDay =  $getData['start_time'].'-01';
                $time = explode('-',$getData['start_time']);
                $endDay = Carbon::create($time[0], $time[1])->endOfMonth()->toDateTimeString();
                $nowTime = date('Y-m-d');
                if($nowTime < $endDay){
                    $endDay = $nowTime;
                }
            }
            //周统计
            if($getData['type'] == '2'){
                $startDay = $getData['start_time'];
                $endDay = $getData['end_time'];
            }
            //列出这周的每一天日期
            $userInfo = $this->userInfo;
            $workId = Db::name('qt_post_work')->where('post_id',$userInfo['post_id'])->value('work_id');
            //获取用户每天打卡次数
            $workRes = Db::name('qt_work')->where('id',$workId)->find();
            //查询周一到周日的打卡时间
            $workNum = Db::name('qt_work_num')->where('work_id',$workRes['id'])->order('week asc')->group('week')->column('type','week');
            $days = $this->getDateFromRange($startDay,$endDay);
            $workDay = 0;
            $sleepDay = 0;
            foreach ($days as $key=>$value){
                $time = explode('-',$value);
                $week = Carbon::create($time[0], $time[1], $time[2])->dayOfWeekIso;
                //查询今日的打卡次数
                $count = Db::name('qt_work_log')
                    ->where(['user_id'=>$userInfo['id'],'group_id'=>$userInfo['group_id'],'day'=>$value,'week'=>$week])
                    ->whereIn('type','1,3,5')
                    ->count();
                $result['data'][$key]['time'] = $value;

                //正常上班
                if($workNum[$week] == '1'){
                    $result['data'][$key]['type'] = '1';//工作日
                    if($count == $workRes['work_num']){
                        $result['data'][$key]['status'] = '1'; //打卡正常
                    }else{
                        $result['data'][$key]['status'] = '0'; //打卡异常
                    }
                    $workDay ++;
                }else{
                    //休息日
                    $result['data'][$key]['type'] = '2';//休息日
                    $result['data'][$key]['status'] = '1'; //打卡正常
                    $sleepDay ++;
                }
            }
            //打卡状态 0 未打卡 1 正常 2 迟到 3 补卡 4 缺卡  5 早退 6 旷工 7外勤
            $startCount = $this->getCount($userInfo,$startDay,$endDay,'2');//迟到
            $endCount = $this->getCount($userInfo,$startDay,$endDay,'5');//早退
            $missingCount = $this->getCount($userInfo,$startDay,$endDay,'4');//缺卡
            $absenteeismCount = $this->getCount($userInfo,$startDay,$endDay,'6');//旷工
            $fieldCount = $this->getCount($userInfo,$startDay,$endDay,'7');//外勤
            $overCount = $this->getCount($userInfo,$startDay,$endDay,'8');//加班
            $duration = Db::name('qt_work_log')
                ->whereBetweenTime('created_time',$startDay,$endDay)
                ->where(['user_id'=>$userInfo['id'],'group_id'=>$userInfo['group_id']])
                ->group('day')
                ->select();
            //统计时间总数并求平均值
            $total = 0;
            $number = count($duration);
            foreach ($duration as $key=>$value){
                if(empty($value['duration'])){
                    unset($value['duration']);
                    $number = $number -  1;
                }else{
                    $total += $value['duration'];
                }
            }
            if(count($duration) == '0'){
                $average = '0';
            }elseif($number == '0'){
                $average = '0';
            }else{
                $average = $total / $number;
            }
            $result['statistics']['late'] = $startCount;//迟到
            $result['statistics']['leave '] = $endCount;//早退
            $result['statistics']['missing '] = $missingCount;//缺卡
            $result['statistics']['absenteeism'] = $absenteeismCount;//旷工
            $result['statistics']['over'] = $overCount;//加班
            $result['statistics']['field'] = $fieldCount;//外勤
            $result['statistics']['duration'] = $average;//平均时长
            $result['statistics']['work_day'] = $workDay;//工作日
            $result['statistics']['sleep_day'] = $sleepDay;//休息日
            $this->result('查询成功',$result,200);
        }
    }



    /**
     * 打卡统计领导查看员工个人统计
     */
    public function team_user()
    {
        if ($this->request->isGet()) {
            //打卡时间
            $getData = $this->request->get();
            if(empty($getData['type']) || empty($getData['start_time'])){
                $this->result('缺少参数','',204);
            }
            if(empty($getData['user_id']) || !isset($getData['user_id'])){
                $this->result('缺少参数','',204);
            }
            //月统计
            if($getData['type'] == '1'){
                $startDay =  $getData['start_time'].'-01';
                $time = explode('-',$getData['start_time']);
                $endDay = Carbon::create($time[0], $time[1])->endOfMonth()->toDateTimeString();
                $nowTime = date('Y-m-d');
                if($nowTime < $endDay){
                    $endDay = $nowTime;
                }
            }
            //周统计
            if($getData['type'] == '2'){
                $startDay = $getData['start_time'];
                $endDay = $getData['end_time'];
            }
//            $startDay =  Carbon::now()->subWeek()->startOfWeek()->toDateTimeString();
//            $endDay = Carbon::now()->subWeek()->endOfWeek()->toDateTimeString();
            //列出这周的每一天日期
            $userInfo = Db::name('qt_users')->where('id',$getData['user_id'])->find();
            //获取用户每天打卡次数
            $workId = Db::name('qt_post_work')->where('post_id',$userInfo['post_id'])->value('work_id');
            $workRes = Db::name('qt_work')->where('id',$workId)->find();
            if(empty($workRes)){
                $this->result('暂未获取到打卡规则','',204);
            }
            //查询周一到周日的打卡时间
            $workNum = Db::name('qt_work_num')->where('work_id',$workRes['id'])->order('week asc')->group('week')->column('type','week');
            $days = $this->getDateFromRange($startDay,$endDay);
            $workDay = 0;
            $sleepDay = 0;
            foreach ($days as $key=>$value){
                $time = explode('-',$value);
                $week = Carbon::create($time[0], $time[1], $time[2])->dayOfWeekIso;
                //查询今日的打卡次数
                $count = Db::name('qt_work_log')
                    ->where(['user_id'=>$userInfo['id'],'group_id'=>$userInfo['group_id'],'day'=>$value,'week'=>$week])
                    ->whereIn('type','1,3,5')
                    ->count();
                $result['data'][$key]['time'] = $value;
                //正常上班
                if($workNum[$week] == '1'){
                    $result['data'][$key]['type'] = '1';//工作日
                    if($count == $workRes['work_num']){
                        $result['data'][$key]['status'] = '1'; //打卡正常
                    }else{
                        $result['data'][$key]['status'] = '0'; //打卡异常
                    }
                    $workDay ++;
                }else{
                    //休息日
                    $result['data'][$key]['type'] = '2';//休息日
                    $result['data'][$key]['status'] = '1'; //打卡正常
                    $sleepDay ++;
                }
            }
            //打卡状态 0 未打卡 1 正常 2 迟到 3 补卡 4 缺卡  5 早退 6 旷工 7外勤
            $startCount = $this->getCount($userInfo,$startDay,$endDay,'2');//迟到
            $endCount = $this->getCount($userInfo,$startDay,$endDay,'5');//早退
            $missingCount = $this->getCount($userInfo,$startDay,$endDay,'4');//缺卡
            $absenteeismCount = $this->getCount($userInfo,$startDay,$endDay,'6');//旷工
            $fieldCount = $this->getCount($userInfo,$startDay,$endDay,'7');//外勤
            $overCount = $this->getCount($userInfo,$startDay,$endDay,'8');//加班
            $duration = Db::name('qt_work_log')
                ->whereBetweenTime('created_time',$startDay,$endDay)
                ->where(['user_id'=>$userInfo['id'],'group_id'=>$userInfo['group_id']])
                ->group('day')
                ->select();
            //统计时间总数并求平均值
            $total = 0;
            $number = count($duration);
            foreach ($duration as $key=>$value){
                if(empty($value['duration'])){
                    unset($value['duration']);
                    $number = $number -  1;
                }else{
                    $total += $value['duration'];
                }
            }
            if(count($duration) == '0'){
                $average = '0';
            }elseif($number == '0'){
                $average = '0';
            }else{
                $average = $total / $number;
            }
            $result['statistics']['late'] = $startCount;//迟到
            $result['statistics']['leave '] = $endCount;//早退
            $result['statistics']['missing '] = $missingCount;//缺卡
            $result['statistics']['absenteeism'] = $absenteeismCount;//旷工
            $result['statistics']['over'] = $overCount;//加班
            $result['statistics']['field'] = $fieldCount;//外勤
            $result['statistics']['duration'] = $average;//平均时长
            $result['statistics']['work_day'] = $workDay;//工作日
            $result['statistics']['sleep_day'] = $sleepDay;//休息日
            $this->result('查询成功',$result,200);
        }
    }




    /**
     * 团队统计每天
     */
    public function team_list()
    {
        if ($this->request->isGet()) {
            //打卡时间
            $getData = $this->request->get();
            if(empty($getData['type']) || empty($getData['start_time'])){
                $this->result('缺少参数','',204);
            }
            //月统计
            if($getData['type'] == '1'){
                $startDay =  $getData['start_time'].'-01';
                $time = explode('-',$getData['start_time']);
                $endDay = Carbon::create($time[0], $time[1])->endOfMonth()->toDateTimeString();
                $nowTime = date('Y-m-d');
                if($nowTime < $endDay){
                    $endDay = $nowTime;
                }
            }
            //周统计
            if($getData['type'] == '2'){
                $startDay = $getData['start_time'];
                $endDay = $getData['end_time'];
            }
//            $startDay =  Carbon::now()->subWeek()->startOfWeek()->toDateTimeString();
//            $endDay = Carbon::now()->subWeek()->endOfWeek()->toDateTimeString();
            //列出这周的每一天日期
            $userInfo = $this->userInfo;
            $days = $this->getDateFromRange($startDay,$endDay);
            foreach ($days as $key=>$value){
                $time = explode('-',$value);
                $week = Carbon::create($time[0], $time[1], $time[2])->dayOfWeekIso;
                //查询今日的打卡次数
                $data['time'] = $value;
                $data['data'] = Db::name('qt_work_team')
                    ->where(['user_id'=>$userInfo['id'],'day'=>$value,'week'=>$week])
                    ->find();
                //有问题的记录
                $error = Db::name('qt_work_team_log')
                    ->field('w.*,u.nickname')
                    ->alias('w')
                    ->leftJoin('qt_users u','w.user_id = u.id')
                    ->where('w.work_team_id',$data['data']['id'])
                    ->select();
                $data['data']['error'] = $error;
                if($data == null){
                    $data['time'] = $value;
                    $data['data'] = [];
                    $data['data']['error'] = [];
                }
                $result[$key] = $data;
            }
            $this->result('查询成功',$result,200);
        }
    }


    /**
     * 团队统计周或者月
     */
    public function team_week()
    {
        if ($this->request->isGet()) {
            //打卡时间
            $getData = $this->request->get();
            if(empty($getData['type']) || empty($getData['start_time'])){
                $this->result('缺少参数','',204);
            }
            //月统计开始结束时间
            if($getData['type'] == '1'){
                $startDay =  $getData['start_time'].'-01';
                $time = explode('-',$getData['start_time']);
                $endDay = Carbon::create($time[0], $time[1])->endOfMonth()->toDateTimeString();
                $nowTime = date('Y-m-d');
                if($nowTime < $endDay){
                    $endDay = $nowTime;
                }
            }
            //周统计开始结束时间
            if($getData['type'] == '2'){
                $startDay = $getData['start_time'];
                $endDay = $getData['end_time'];
            }
            //列出这周的每一天日期
            $userInfo = $this->userInfo;
            $days = $this->getDateFromRange($startDay,$endDay);
            //查询是否有周或者月统计记录
            if($getData['type'] == '1'){$type = '3';}
            if($getData['type'] == '2'){$type = '2';}
            $find = Db::name('qt_work_team')->where(['day'=>$startDay,'type'=>$type])->find();
            //存在直接返回数据
            if($find){
                $error = Db::name('qt_work_team_log')
                    ->field('w.*,u.nickname')
                    ->alias('w')
                    ->leftJoin('qt_users u','w.user_id = u.id')
                    ->where('w.work_team_id',$find['id'])
                    ->select();
                $find['error'] = $error;
                $this->result('查询成功',$find,200);
            }else{
                //计算这段时间的数据
                $insertData['late'] = '0';//迟到人数
                $insertData['missing'] = '0';//缺卡人数
                $insertData['leave'] = '0';//请假人数
                $insertData['absenteeism'] = '0'; //旷工人数
                $insertData['over'] = '0';//加班人数
                $insertData['field'] = '0';//早退人数
                $insertData['duration'] = '0';//平局时长
                $insertData['day'] = $startDay;//平局时长
                $i = 0;
                $insertData['week'] = Carbon::create($startDay)->dayOfWeekIso;
                foreach ($days as $key=>$value){
                    $res = Db::name('qt_work_team')->where('day',$value)->find();
                    if(!empty($res)){
                        if($res['duration'] != '' || $res['duration'] != null){
                            $i++;
                        }
                        $insertData['late'] += $res['late'];
                        $insertData['missing'] += $res['missing'];
                        $insertData['leave'] += $res['leave'];
                        $insertData['absenteeism'] += $res['absenteeism'];
                        $insertData['over'] += $res['over'];
                        $insertData['field'] += $res['field'];
                        $insertData['duration'] += $res['duration'];
                    }
                }
                if($i == '0'){
                    $insertData['duration'] = '0';
                }else{
                    $insertData['duration'] =round(( $insertData['duration'] / $i),1);
                }
                //获取到统计的ID
                $work_team_id = $this->insert($userInfo,$insertData,$type);
                $i = 0;
                $errorData = [];
                foreach ($days as $key=>$value){
                    $res = Db::name('qt_work_team')->where('day',$value)->find();
                    if(!empty($res)){
                        //查询每天的错误
                        $error = Db::name('qt_work_team_log')->where('work_team_id',$res['id'])->select();
                        if(!empty($error)){
                            foreach ($error as $k=>$v){
                                $errorData[$i]['work_team_id'] = $work_team_id;
                                $errorData[$i]['user_id'] = $v['user_id'];
                                $errorData[$i]['time'] = $v['time'];
                                $errorData[$i]['type'] = $v['type'];
                            }
                        }
                    }
                }
                //批量插入错误信息
                Db::name('qt_work_team_log')->insertAll($errorData);
                $result  = Db::name('qt_work_team')->where(['id'=>$work_team_id])->find();
                $error = Db::name('qt_work_team_log')
                    ->field('w.*,u.nickname')
                    ->alias('w')
                    ->leftJoin('qt_users u','w.user_id = u.id')
                    ->where('w.work_team_id',$result['id'])
                    ->select();
                $result['error'] = $error;
                $this->result('查询成功',$result,200);
            }
            $this->result('查询成功',$result,200);
        }
    }


    /**
     * 插入团队周或者月统计
     * @param $userInfo
     * @param $data
     * @param $type
     * @return int|string
     */
    public function insert($userInfo,$data,$type){
        $insert['user_id'] = $userInfo['id'];
        $insert['group_id'] = $userInfo['group_id'];
        $insert['week'] = $data['week'];
        $insert['day'] = $data['day'];
        $insert['late'] = $data['late'];
        $insert['missing'] = $data['missing'];
        $insert['leave'] = $data['leave'];
        $insert['absenteeism'] = $data['absenteeism'];
        $insert['over'] = $data['over'];
        $insert['field'] = $data['field'];
        $insert['duration'] = $data['duration'];
        $insert['type'] = $type;
        $id = Db::name('qt_work_team')->insertGetId($insert);
        return $id;
    }


    /**
     * 获取统计次数
     * @param $userInfo [用户信息]
     * @param $startDay [开始日期]
     * @param $endDay [结束日期]
     * @param $type [类型]打卡状态 0 未打卡 1 正常 2 迟到 3 补卡 4 缺卡  5 早退 6 旷工
     * @return float|int|string
     */
    function getCount($userInfo,$startDay,$endDay,$type){
        $startCount = Db::name('qt_work_log')
            ->whereBetweenTime('created_time',$startDay,$endDay)
            ->where(['user_id'=>$userInfo['id'],'group_id'=>$userInfo['group_id']])
            ->where('type',$type)
            ->count();
        return $startCount;
    }

    /**
     * 获取指定日期段内每一天的日期
     * @param  Date  $startdate 开始日期
     * @param  Date  $enddate   结束日期
     * @return Array
     */
    function getDateFromRange($startdate, $enddate){

        $stimestamp = strtotime($startdate);
        $etimestamp = strtotime($enddate);

        // 计算日期段内有多少天
        $days = ($etimestamp-$stimestamp)/86400+1;

        // 保存每天日期
        $date = array();

        for($i=0; $i<$days; $i++){
            $date[] = date('Y-m-d', $stimestamp+(86400*$i));
        }
        return $date;
    }


    /**
     * 打卡
     */
    public function clock(){
        if ($this->request->isPost()) {
            //打卡位置
            $getData = $this->request->post();
            if(empty($getData['clock_id'])){
                $this->result('缺少参数', '', 204);
            }
            $find = Db::name('qt_work_log')->where('id',$getData['clock_id'])->find();
            $late = Db::name('qt_work')->where('id',$find['work_id'])->value('late');
            //上班卡
            if($find['work_type'] == '1'){
                $creat_time = $find['created_time'] + ($late*60);
                $nowTime = time();
                if($nowTime <= $creat_time){
                    $type = '1';
                }else{
                    $type = '2';
                }
            }
            //下班卡
            if($find['work_type'] == '2'){
                $creat_time = $find['created_time'];
                $nowTime = time();
                if($nowTime <= $creat_time){
                    $type = '5';
                }else{
                    $type = '1';
                }
            }
            $save = Db::name('qt_work_log')->where('id',$getData['clock_id'])->update(['type'=>$type,'clock_time'=>$nowTime]);
            if($save){
                $this->result('打卡成功', '', 200);
            }
            $this->result('打卡失败', '', 204);
        }
        $this->result('无效的请求', '', 204);
    }


    /**
     * 考勤打卡说明
     */
    public function explain(){
        if ($this->request->isGet()) {
            //打卡位置
            $userInfo = $this->userInfo;
            $data = Db::name('qt_work')
                ->alias('w')
                ->field('w.time_rule,w.work_rule,w.repair_rule,wc.address,wc.distance')
                ->leftJoin('qt_work_config wc','wc.group_id = w.group_id')
                ->where(['w.group_id'=>$userInfo['group_id'],'w.post_id'=>$userInfo['post_id']])
                ->find();
            $this->result('查询成功',$data,200);
        }
        $this->result('无效的请求', '', 204);
    }


    /**
     * @param $data
     */
    public function getData($userInfo,$data){
        $week = Carbon::now()->dayOfWeek;//星期
        $day = Carbon::now()->toDateString();
        $startTime = $day.' '.$data['start_time'];
        $startTime = strtotime($startTime);
        $endTime = $day.' '.$data['end_time'];
        $endTime = strtotime($endTime);
        $insertData[0]['user_id'] = $userInfo['id'];
        $insertData[0]['group_id'] = $userInfo['group_id'];
        $insertData[0]['work_id'] = $data['work_id'];
        $insertData[0]['work_time_id'] = $data['id'];
        $insertData[0]['week'] =$week;
        $insertData[0]['day'] =$day;
        $insertData[0]['work_type'] ='1';
        $insertData[0]['created_time'] = $startTime;
        $insertData[0]['type'] = '0';
        $insertData[1]['user_id'] = $userInfo['id'];
        $insertData[1]['group_id'] = $userInfo['group_id'];
        $insertData[1]['work_id'] = $data['work_id'];
        $insertData[1]['work_time_id'] = $data['id'];
        $insertData[1]['week'] =$week;
        $insertData[1]['day'] =$day;
        $insertData[1]['work_type'] ='2';
        $insertData[1]['created_time'] = $endTime;
        $insertData[1]['type'] = '0';
        return $insertData;
    }

    /**
     * 获取下级用户
     * @param $userInfo
     */
    public function getSonUser($userInfo){
        $pidRes = Db::name('qt_post')->where('post_pid',$userInfo['post_id'])->column('id');
        $userRes = Db::name('qt_users')
            ->alias('u')
            ->leftJoin('qt_post p','p.id = u.post_id')
            ->field('u.id,u.nickname,p.title')
            ->where('u.group_id',$userInfo['group_id'])
            ->whereIn('p.id',$pidRes)
            ->select();
        return $userRes;
    }


}
